package cn.edu.dlut.WingGame.Object;

import cn.edu.dlut.WingGame.BaseType.ObjectState;
import cn.edu.dlut.WingGame.Tools.ObjectContainer;

public abstract class WingObjectPool extends WingObject {
	protected boolean updateState = true;
	protected int max = 50;
	protected ObjectContainer usedContainer;
	protected ObjectContainer oldContainer;

	public WingObjectPool() {
		usedContainer = new ObjectContainer();
		oldContainer = new ObjectContainer();
	}

	public WingObjectPool(String name) {
		super(name);
		usedContainer = new ObjectContainer();
		oldContainer = new ObjectContainer();
	}

	public void setUpdateState(boolean flag) {
		this.updateState = flag;
	}

	public boolean getUpdateState() {
		return updateState;
	}

	public void setMax(int max) {
		this.max = max;
	}

	public int getMax() {
		return max;
	}

	public int getSize() {
		return usedContainer.getSize();
	}

	public WingObject getObject(int index) {
		return usedContainer.getObject(index);
	}

	public WingObject getObjectByID(int id) {
		return usedContainer.getObjectByID(id);
	}

	public WingObject getObject() {
		WingObject obj;
		if (oldContainer.isEmpty()) {
			obj = newObject();
		} else {
			obj = oldContainer.getObject(0);
			oldContainer.delObject(0);
		}
		usedContainer.addObject(obj);
		return obj;
	}

	public synchronized void delObject(WingObject obj) {
		if (usedContainer.getSize() < max)
			oldContainer.addObject(obj);
		usedContainer.delObjectByID(obj.mID);
	}

	public synchronized void delObject(int id) {
		if (usedContainer.getSize() < max)
			oldContainer.addObject(usedContainer.getObjectByID(id));
		usedContainer.delObjectByID(id);
	}

	public synchronized void clear() {
		WingObject obj;
		for (int i = 0; i < usedContainer.getSize(); i++) {
			obj = usedContainer.getObject(i);
			obj.setState(ObjectState.died);
			oldContainer.addObject(obj);
		}
		usedContainer.delAllObject();
	}

	public abstract WingObject newObject();

	@Override
	public void render() {
		WingObject obj;
		for (int i = 0; i < usedContainer.getSize(); i++) {
			obj = usedContainer.getObject(i);
			if (updateState) {
				if (obj.mState == ObjectState.normal
						|| obj.mState == ObjectState.render)
					obj.render();
			}
		}
	}

	@Override
	public void update() {
		WingObject obj;
		for (int i = 0; i < usedContainer.getSize(); i++) {
			obj = usedContainer.getObject(i);
			if (obj.getState() == ObjectState.died) {
				delObject(obj);
				i--;
			} else if (updateState) {
				if (obj.mState == ObjectState.normal
						|| obj.mState == ObjectState.update)
					obj.update();
			}
		}
	}
}
